package cn.bingoo.handy;

import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Hashtable;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.UndoableEditEvent;
import javax.swing.event.UndoableEditListener;
import javax.swing.text.Document;
import javax.swing.text.JTextComponent;
import javax.swing.undo.CannotRedoException;
import javax.swing.undo.CannotUndoException;
import javax.swing.undo.UndoManager;

import cn.bingoo.lang.Encoding;
import cn.bingoo.swing.utils.Clipboards;

public class TranscoderFrame extends JFrame
{
    private static final long serialVersionUID = 5712516501903313109L;
    protected UndoManager undo = new UndoManager();
    protected UndoAction undoAction;
    protected RedoAction redoAction;
    private Hashtable<Object, Action> actions;
    private JButton base64DecodeButton;
    private JButton base64EncodeButton;
    private JLabel countLabel;
    private JScrollPane jScrollPane1;
    private JButton md5hashButton;
    private JButton sha1hashButton;
    private JTextPane textPane;
    private JButton urlDecodeButton;
    private JButton urlEncodeButton;
    private JTextPane resultTextPane;
    private JScrollPane scrollPane;
    private JLabel resultCountLabel;
    private JPanel panel;
    private JButton btnSwap;
    private JButton btnClean;
    private JButton btnCopy;
    private JButton btnPaste;
    private JPanel panel_1;
    private JButton btnClean_1;
    private JButton btnCopy_1;
    private JButton btnPaste_1;
    private JButton btnLongtodate;
    private JButton btnDatetolong;
    private JTextField txtDateFormat;
    private JButton btnNow;
    private JButton btnToday;
    private JButton btnNewButton;
    private JTextField txtPass;
    private JTabbedPane tabbedPane;
    private JPanel panel_2;
    private JPanel panel_3;
    private JTextField txtPubicKey;
    private JLabel lblPasswordpublicKey;
    private JLabel lblPrivateKey;
    private JTextField txtPrivateKey;
    private JButton btnUnicodeEncode;
    private JButton btnUnicodeDecode;
    private JPanel panel_4;
    private JLabel lblFind;
    private JTextField textField;
    private JLabel lblReplace;
    private JTextField textField_1;
    private JCheckBox chckbxUseRegex;
    private JButton btnFind;
    private JButton btnReplace;
    private JTextPane txtpnJavayyyymmddHhmmsssssOracleyyyymmdd;
    private JButton btnAes;
    private JButton btndesEncrypt;
    private JButton btnAesEnrypt;
    private JButton btnAesDecrypt;
    private JCheckBox chckbxCrlf;

    public TranscoderFrame()
    {
        initComponents();
        createActionTable(this.textPane);

        this.undo.setLimit(10);
        this.undoAction = new UndoAction();
        this.redoAction = new RedoAction();

        final Document d = this.textPane.getDocument();
        d.addUndoableEditListener(new MyUndoableEditListener());
        d.addDocumentListener(new DocumentListener() {
            @Override
            public void changedUpdate(DocumentEvent evt) {
                update();
            }

            @Override
            public void insertUpdate(DocumentEvent evt) {
                update();
            }

            @Override
            public void removeUpdate(DocumentEvent evt) {
                update();
            }

            private void update() {
                TranscoderFrame.this.countLabel.setText("Chars: " + d.getLength());
            }
        });

        final Document d1 = this.resultTextPane.getDocument();
        d1.addUndoableEditListener(new MyUndoableEditListener());
        d1.addDocumentListener(new DocumentListener() {
            @Override
            public void changedUpdate(DocumentEvent evt) {
                update();
            }

            @Override
            public void insertUpdate(DocumentEvent evt) {
                update();
            }

            @Override
            public void removeUpdate(DocumentEvent evt) {
                update();
            }

            private void update() {
                TranscoderFrame.this.resultCountLabel.setText("Chars: " + d1.getLength());
            }
        });

    }

    private void createActionTable(JTextComponent textComponent)
    {
        this.actions = new Hashtable<Object, Action>();
        Action[] actionsArray = textComponent.getActions();
        for (Action a : actionsArray) {
            this.actions.put(a.getValue("Name"), a);
        }
    }

    private void initComponents()
    {

        setTitle("Transcoder");
        GridBagLayout gridBagLayout = new GridBagLayout();
        gridBagLayout.columnWidths = new int[] { 592, 0 };
        gridBagLayout.rowHeights = new int[] { 0, 37, 0, 0, 0, 0 };
        gridBagLayout.columnWeights = new double[] { 1.0, Double.MIN_VALUE };
        gridBagLayout.rowWeights = new double[] { 0.0, 1.0, 0.0, 1.0, 0.0, Double.MIN_VALUE };
        getContentPane().setLayout(gridBagLayout);

        panel_1 = new JPanel();
        GridBagConstraints gbc_panel_1 = new GridBagConstraints();
        gbc_panel_1.insets = new Insets(0, 0, 5, 0);
        gbc_panel_1.fill = GridBagConstraints.BOTH;
        gbc_panel_1.gridx = 0;
        gbc_panel_1.gridy = 0;
        getContentPane().add(panel_1, gbc_panel_1);
        GridBagLayout gbl_panel_1 = new GridBagLayout();
        gbl_panel_1.columnWidths = new int[] { 0, 0, 0, 0, 0, 0, 0 };
        gbl_panel_1.rowHeights = new int[] { 0, 0 };
        gbl_panel_1.columnWeights = new double[] { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Double.MIN_VALUE };
        gbl_panel_1.rowWeights = new double[] { 0.0, Double.MIN_VALUE };
        panel_1.setLayout(gbl_panel_1);
        this.countLabel = new JLabel();
        GridBagConstraints gbc_countLabel = new GridBagConstraints();
        gbc_countLabel.insets = new Insets(0, 0, 0, 5);
        gbc_countLabel.gridx = 0;
        gbc_countLabel.gridy = 0;
        panel_1.add(countLabel, gbc_countLabel);

        this.countLabel.setText("Chars: 0");

        btnClean_1 = new JButton("Clean");
        btnClean_1.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                textPane.setText("");
            }
        });
        GridBagConstraints gbc_btnClean_1 = new GridBagConstraints();
        gbc_btnClean_1.insets = new Insets(0, 0, 0, 5);
        gbc_btnClean_1.gridx = 1;
        gbc_btnClean_1.gridy = 0;
        panel_1.add(btnClean_1, gbc_btnClean_1);

        btnCopy_1 = new JButton("Copy");
        btnCopy_1.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                Clipboards.setClipboard(textPane.getText());
            }
        });
        GridBagConstraints gbc_btnCopy_1 = new GridBagConstraints();
        gbc_btnCopy_1.insets = new Insets(0, 0, 0, 5);
        gbc_btnCopy_1.gridx = 2;
        gbc_btnCopy_1.gridy = 0;
        panel_1.add(btnCopy_1, gbc_btnCopy_1);

        btnPaste_1 = new JButton("Paste");
        btnPaste_1.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String clipboard = Clipboards.getClipboard();
                textPane.setText(clipboard);
            }
        });
        GridBagConstraints gbc_btnPaste_1 = new GridBagConstraints();
        gbc_btnPaste_1.insets = new Insets(0, 0, 0, 5);
        gbc_btnPaste_1.gridx = 3;
        gbc_btnPaste_1.gridy = 0;
        panel_1.add(btnPaste_1, gbc_btnPaste_1);

        btnNow = new JButton("Now");
        btnNow.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (textPane.getSelectionEnd() == textPane.getSelectionStart()) {
                    textPane.select(0, textPane.getText().length());
                }
                SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                textPane.replaceSelection(fmt.format(new Date()));
            }
        });
        GridBagConstraints gbc_btnNow = new GridBagConstraints();
        gbc_btnNow.insets = new Insets(0, 0, 0, 5);
        gbc_btnNow.gridx = 4;
        gbc_btnNow.gridy = 0;
        panel_1.add(btnNow, gbc_btnNow);

        btnToday = new JButton("Today");
        btnToday.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (textPane.getSelectionEnd() == textPane.getSelectionStart()) {
                    textPane.select(0, textPane.getText().length());
                }
                SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
                textPane.replaceSelection(fmt.format(new Date()));
            }
        });
        GridBagConstraints gbc_btnToday = new GridBagConstraints();
        gbc_btnToday.gridx = 5;
        gbc_btnToday.gridy = 0;
        panel_1.add(btnToday, gbc_btnToday);
        this.jScrollPane1 = new JScrollPane();
        this.textPane = new JTextPane();
        this.textPane.setFont(new Font("微软雅黑", Font.PLAIN, 12));
        this.jScrollPane1.setViewportView(this.textPane);

        GridBagConstraints gbc_jScrollPane1 = new GridBagConstraints();
        gbc_jScrollPane1.fill = GridBagConstraints.BOTH;
        gbc_jScrollPane1.insets = new Insets(0, 0, 5, 0);
        gbc_jScrollPane1.gridx = 0;
        gbc_jScrollPane1.gridy = 1;
        getContentPane().add(this.jScrollPane1, gbc_jScrollPane1);

        panel = new JPanel();
        GridBagConstraints gbc_panel = new GridBagConstraints();
        gbc_panel.insets = new Insets(0, 0, 5, 0);
        gbc_panel.fill = GridBagConstraints.BOTH;
        gbc_panel.gridx = 0;
        gbc_panel.gridy = 2;
        getContentPane().add(panel, gbc_panel);
        GridBagLayout gbl_panel = new GridBagLayout();
        gbl_panel.columnWidths = new int[] { 0, 0, 0, 0, 0, 0, 0, 0 };
        gbl_panel.rowHeights = new int[] { 0, 0 };
        gbl_panel.columnWeights = new double[] { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, Double.MIN_VALUE };
        gbl_panel.rowWeights = new double[] { 0.0, Double.MIN_VALUE };
        panel.setLayout(gbl_panel);

        resultCountLabel = new JLabel("Chars: 0");
        GridBagConstraints gbc_resultCountLabel = new GridBagConstraints();
        gbc_resultCountLabel.insets = new Insets(0, 0, 0, 5);
        gbc_resultCountLabel.gridx = 0;
        gbc_resultCountLabel.gridy = 0;
        panel.add(resultCountLabel, gbc_resultCountLabel);

        btnSwap = new JButton("Swap");
        btnSwap.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String from = textPane.getText();
                textPane.setText(resultTextPane.getText());
                resultTextPane.setText(from);
            }
        });
        GridBagConstraints gbc_btnSwap = new GridBagConstraints();
        gbc_btnSwap.insets = new Insets(0, 0, 0, 5);
        gbc_btnSwap.gridx = 1;
        gbc_btnSwap.gridy = 0;
        panel.add(btnSwap, gbc_btnSwap);

        btnClean = new JButton("Clean");
        btnClean.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                resultTextPane.setText("");
            }
        });
        GridBagConstraints gbc_btnClean = new GridBagConstraints();
        gbc_btnClean.insets = new Insets(0, 0, 0, 5);
        gbc_btnClean.gridx = 2;
        gbc_btnClean.gridy = 0;
        panel.add(btnClean, gbc_btnClean);

        btnCopy = new JButton("Copy");
        btnCopy.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                Clipboards.setClipboard(resultTextPane.getText());
            }
        });
        GridBagConstraints gbc_btnCopy = new GridBagConstraints();
        gbc_btnCopy.insets = new Insets(0, 0, 0, 5);
        gbc_btnCopy.gridx = 3;
        gbc_btnCopy.gridy = 0;
        panel.add(btnCopy, gbc_btnCopy);

        btnPaste = new JButton("Paste");
        btnPaste.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String clipboard = Clipboards.getClipboard();
                resultTextPane.setText(clipboard);
            }
        });
        GridBagConstraints gbc_btnPaste = new GridBagConstraints();
        gbc_btnPaste.insets = new Insets(0, 0, 0, 5);
        gbc_btnPaste.gridx = 4;
        gbc_btnPaste.gridy = 0;
        panel.add(btnPaste, gbc_btnPaste);

        scrollPane = new JScrollPane();
        GridBagConstraints gbc_scrollPane = new GridBagConstraints();
        gbc_scrollPane.fill = GridBagConstraints.BOTH;
        gbc_scrollPane.insets = new Insets(0, 0, 5, 0);
        gbc_scrollPane.gridx = 0;
        gbc_scrollPane.gridy = 3;
        getContentPane().add(scrollPane, gbc_scrollPane);

        resultTextPane = new JTextPane();
        resultTextPane.setFont(new Font("微软雅黑", Font.PLAIN, 12));
        scrollPane.setViewportView(resultTextPane);

        tabbedPane = new JTabbedPane(JTabbedPane.TOP);
        GridBagConstraints gbc_tabbedPane = new GridBagConstraints();
        gbc_tabbedPane.fill = GridBagConstraints.BOTH;
        gbc_tabbedPane.gridx = 0;
        gbc_tabbedPane.gridy = 4;
        getContentPane().add(tabbedPane, gbc_tabbedPane);

        panel_2 = new JPanel();
        tabbedPane.addTab("Encode/Decode", null, panel_2, null);
        GridBagLayout gbl_panel_2 = new GridBagLayout();
        gbl_panel_2.columnWidths = new int[] { 0, 0, 0, 0, 0 };
        gbl_panel_2.rowHeights = new int[] { 0, 0, 0, 0, 0 };
        gbl_panel_2.columnWeights = new double[] { 0.0, 0.0, 0.0, 1.0, Double.MIN_VALUE };
        gbl_panel_2.rowWeights = new double[] { 0.0, 0.0, 0.0, 0.0, Double.MIN_VALUE };
        panel_2.setLayout(gbl_panel_2);
        this.urlEncodeButton = new JButton();
        GridBagConstraints gbc_urlEncodeButton = new GridBagConstraints();
        gbc_urlEncodeButton.fill = GridBagConstraints.HORIZONTAL;
        gbc_urlEncodeButton.insets = new Insets(0, 0, 5, 5);
        gbc_urlEncodeButton.gridx = 0;
        gbc_urlEncodeButton.gridy = 0;
        panel_2.add(urlEncodeButton, gbc_urlEncodeButton);

        this.urlEncodeButton.setText("URL encode");
        this.urlDecodeButton = new JButton();
        GridBagConstraints gbc_urlDecodeButton = new GridBagConstraints();
        gbc_urlDecodeButton.fill = GridBagConstraints.HORIZONTAL;
        gbc_urlDecodeButton.insets = new Insets(0, 0, 5, 5);
        gbc_urlDecodeButton.gridx = 1;
        gbc_urlDecodeButton.gridy = 0;
        panel_2.add(urlDecodeButton, gbc_urlDecodeButton);

        this.urlDecodeButton.setText("URL decode");
        this.urlDecodeButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent evt) {
                TranscoderFrame.this.urlDecodeButtonActionPerformed(evt);
            }
        });
        this.md5hashButton = new JButton();
        GridBagConstraints gbc_md5hashButton = new GridBagConstraints();
        gbc_md5hashButton.fill = GridBagConstraints.HORIZONTAL;
        gbc_md5hashButton.insets = new Insets(0, 0, 5, 5);
        gbc_md5hashButton.gridx = 2;
        gbc_md5hashButton.gridy = 0;
        panel_2.add(md5hashButton, gbc_md5hashButton);

        this.md5hashButton.setText("MD5 hash");
        this.md5hashButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent evt) {
                TranscoderFrame.this.md5hashButtonActionPerformed(evt);
            }
        });
        this.sha1hashButton = new JButton();
        GridBagConstraints gbc_sha1hashButton = new GridBagConstraints();
        gbc_sha1hashButton.insets = new Insets(0, 0, 5, 0);
        gbc_sha1hashButton.anchor = GridBagConstraints.WEST;
        gbc_sha1hashButton.gridx = 3;
        gbc_sha1hashButton.gridy = 0;
        panel_2.add(sha1hashButton, gbc_sha1hashButton);

        this.sha1hashButton.setText("SHA-1 hash");
        this.sha1hashButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent evt) {
                TranscoderFrame.this.sha1hashButtonActionPerformed(evt);
            }
        });
        this.base64EncodeButton = new JButton();
        GridBagConstraints gbc_base64EncodeButton = new GridBagConstraints();
        gbc_base64EncodeButton.fill = GridBagConstraints.HORIZONTAL;
        gbc_base64EncodeButton.insets = new Insets(0, 0, 5, 5);
        gbc_base64EncodeButton.gridx = 0;
        gbc_base64EncodeButton.gridy = 1;
        panel_2.add(base64EncodeButton, gbc_base64EncodeButton);

        this.base64EncodeButton.setText("Base64 encode");
        this.base64DecodeButton = new JButton();
        GridBagConstraints gbc_base64DecodeButton = new GridBagConstraints();
        gbc_base64DecodeButton.fill = GridBagConstraints.HORIZONTAL;
        gbc_base64DecodeButton.insets = new Insets(0, 0, 5, 5);
        gbc_base64DecodeButton.gridx = 1;
        gbc_base64DecodeButton.gridy = 1;
        panel_2.add(base64DecodeButton, gbc_base64DecodeButton);

        this.base64DecodeButton.setText("Base64 decode");

        btnNewButton = new JButton("HmacMD5");
        GridBagConstraints gbc_btnNewButton = new GridBagConstraints();
        gbc_btnNewButton.fill = GridBagConstraints.HORIZONTAL;
        gbc_btnNewButton.insets = new Insets(0, 0, 5, 5);
        gbc_btnNewButton.gridx = 2;
        gbc_btnNewButton.gridy = 1;
        panel_2.add(btnNewButton, gbc_btnNewButton);

        txtPass = new JTextField();
        GridBagConstraints gbc_txtPass = new GridBagConstraints();
        gbc_txtPass.fill = GridBagConstraints.HORIZONTAL;
        gbc_txtPass.insets = new Insets(0, 0, 5, 0);
        gbc_txtPass.gridx = 3;
        gbc_txtPass.gridy = 1;
        panel_2.add(txtPass, gbc_txtPass);
        txtPass.setText("password");
        txtPass.setFont(new Font("Consolas", Font.PLAIN, 12));
        txtPass.setColumns(10);

        chckbxCrlf = new JCheckBox("BASE64 CRLF");
        GridBagConstraints gbc_chckbxCrlf = new GridBagConstraints();
        gbc_chckbxCrlf.insets = new Insets(0, 0, 5, 5);
        gbc_chckbxCrlf.gridx = 0;
        gbc_chckbxCrlf.gridy = 2;
        panel_2.add(chckbxCrlf, gbc_chckbxCrlf);

        btnLongtodate = new JButton("LongToDate");
        GridBagConstraints gbc_btnLongtodate = new GridBagConstraints();
        gbc_btnLongtodate.fill = GridBagConstraints.HORIZONTAL;
        gbc_btnLongtodate.insets = new Insets(0, 0, 5, 5);
        gbc_btnLongtodate.gridx = 1;
        gbc_btnLongtodate.gridy = 2;
        panel_2.add(btnLongtodate, gbc_btnLongtodate);
        btnLongtodate.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String dateFormat = txtDateFormat.getText() != null ? txtDateFormat.getText() : "yyyy-MM-dd HH:mm:ss";
                try {
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dateFormat);
                    if (textPane.getSelectionEnd() == textPane.getSelectionStart()) {
                        textPane.select(0, textPane.getText().length());
                    }
                    String selectedText = textPane.getSelectedText();
                    String date = simpleDateFormat.format(new Date(Long.parseLong(selectedText)));
                    resultTextPane.setText(date);
                }
                catch (Exception e1) {
                    e1.printStackTrace();
                    resultTextPane.setText("Exception! " + e1.toString());
                }
            }
        });

        btnDatetolong = new JButton("DateToLong");
        GridBagConstraints gbc_btnDatetolong = new GridBagConstraints();
        gbc_btnDatetolong.fill = GridBagConstraints.HORIZONTAL;
        gbc_btnDatetolong.insets = new Insets(0, 0, 5, 5);
        gbc_btnDatetolong.gridx = 2;
        gbc_btnDatetolong.gridy = 2;
        panel_2.add(btnDatetolong, gbc_btnDatetolong);
        btnDatetolong.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String dateFormat = txtDateFormat.getText() != null ? txtDateFormat.getText() : "yyyy-MM-dd HH:mm:ss";
                try {
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dateFormat);
                    if (textPane.getSelectionEnd() == textPane.getSelectionStart()) {
                        textPane.select(0, textPane.getText().length());
                    }
                    String selectedText = textPane.getSelectedText();

                    Date date = simpleDateFormat.parse(selectedText);
                    resultTextPane.setText("" + date.getTime());
                }
                catch (Exception e1) {
                    e1.printStackTrace();
                    resultTextPane.setText("Exception! " + e1.toString());
                }

            }
        });

        txtDateFormat = new JTextField();
        GridBagConstraints gbc_txtDateFormat = new GridBagConstraints();
        gbc_txtDateFormat.insets = new Insets(0, 0, 5, 0);
        gbc_txtDateFormat.fill = GridBagConstraints.HORIZONTAL;
        gbc_txtDateFormat.gridx = 3;
        gbc_txtDateFormat.gridy = 2;
        panel_2.add(txtDateFormat, gbc_txtDateFormat);
        txtDateFormat.setFont(new Font("Consolas", Font.PLAIN, 12));
        txtDateFormat.setText("yyyy-MM-dd HH:mm:ss");
        txtDateFormat.setColumns(10);

        btnUnicodeEncode = new JButton("Unicode encode");
        btnUnicodeEncode.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (textPane.getSelectionEnd() == textPane.getSelectionStart()) {
                    textPane.select(0, textPane.getText().length());
                }
                String selectedText = textPane.getSelectedText();
                resultTextPane.setText(Encoding.escapeUnicode(selectedText));
            }
        });
        GridBagConstraints gbc_btnUnicodeEncode = new GridBagConstraints();
        gbc_btnUnicodeEncode.fill = GridBagConstraints.HORIZONTAL;
        gbc_btnUnicodeEncode.insets = new Insets(0, 0, 0, 5);
        gbc_btnUnicodeEncode.gridx = 0;
        gbc_btnUnicodeEncode.gridy = 3;
        panel_2.add(btnUnicodeEncode, gbc_btnUnicodeEncode);

        btnUnicodeDecode = new JButton("Unicode decode");
        btnUnicodeDecode.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (textPane.getSelectionEnd() == textPane.getSelectionStart()) {
                    textPane.select(0, textPane.getText().length());
                }
                String selectedText = textPane.getSelectedText();
                resultTextPane.setText(Encoding.unescapeUnicode(selectedText));
            }
        });
        GridBagConstraints gbc_btnUnicodeDecode = new GridBagConstraints();
        gbc_btnUnicodeDecode.fill = GridBagConstraints.HORIZONTAL;
        gbc_btnUnicodeDecode.insets = new Insets(0, 0, 0, 5);
        gbc_btnUnicodeDecode.gridx = 1;
        gbc_btnUnicodeDecode.gridy = 3;
        panel_2.add(btnUnicodeDecode, gbc_btnUnicodeDecode);
        btnNewButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (textPane.getSelectionEnd() == textPane.getSelectionStart()) {
                    textPane.select(0, textPane.getText().length());
                }
                String result = Encoding.hashHMAC(textPane.getSelectedText(), txtPass.getText());
                resultTextPane.setText(result);
            }
        });
        this.base64DecodeButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent evt) {
                TranscoderFrame.this.base64DecodeButtonActionPerformed(evt);
            }
        });
        this.base64EncodeButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent evt) {
                TranscoderFrame.this.base64EncodeButtonActionPerformed(evt);
            }
        });
        this.urlEncodeButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent evt) {
                TranscoderFrame.this.urlEncodeButtonActionPerformed(evt);
            }
        });

        panel_3 = new JPanel();
        tabbedPane.addTab("Encrypt/Decrypt", null, panel_3, null);
        GridBagLayout gbl_panel_3 = new GridBagLayout();
        gbl_panel_3.columnWidths = new int[] { 0, 0, 0, 0, 0, 0 };
        gbl_panel_3.rowHeights = new int[] { 0, 0, 0, 0, 0 };
        gbl_panel_3.columnWeights = new double[] { 0.0, 0.0, 0.0, 0.0, 1.0, Double.MIN_VALUE };
        gbl_panel_3.rowWeights = new double[] { 0.0, 0.0, 0.0, 0.0, Double.MIN_VALUE };
        panel_3.setLayout(gbl_panel_3);

        lblPasswordpublicKey = new JLabel("Password/Public Key:");
        GridBagConstraints gbc_lblPasswordpublicKey = new GridBagConstraints();
        gbc_lblPasswordpublicKey.insets = new Insets(0, 0, 5, 5);
        gbc_lblPasswordpublicKey.anchor = GridBagConstraints.EAST;
        gbc_lblPasswordpublicKey.gridx = 0;
        gbc_lblPasswordpublicKey.gridy = 0;
        panel_3.add(lblPasswordpublicKey, gbc_lblPasswordpublicKey);

        txtPubicKey = new JTextField();
        GridBagConstraints gbc_txtPubicKey = new GridBagConstraints();
        gbc_txtPubicKey.gridwidth = 4;
        gbc_txtPubicKey.insets = new Insets(0, 0, 5, 0);
        gbc_txtPubicKey.fill = GridBagConstraints.HORIZONTAL;
        gbc_txtPubicKey.gridx = 1;
        gbc_txtPubicKey.gridy = 0;
        panel_3.add(txtPubicKey, gbc_txtPubicKey);
        txtPubicKey.setColumns(10);

        lblPrivateKey = new JLabel("Private Key:");
        GridBagConstraints gbc_lblPrivateKey = new GridBagConstraints();
        gbc_lblPrivateKey.anchor = GridBagConstraints.EAST;
        gbc_lblPrivateKey.insets = new Insets(0, 0, 5, 5);
        gbc_lblPrivateKey.gridx = 0;
        gbc_lblPrivateKey.gridy = 1;
        panel_3.add(lblPrivateKey, gbc_lblPrivateKey);

        txtPrivateKey = new JTextField();
        GridBagConstraints gbc_txtPrivateKey = new GridBagConstraints();
        gbc_txtPrivateKey.gridwidth = 4;
        gbc_txtPrivateKey.insets = new Insets(0, 0, 5, 0);
        gbc_txtPrivateKey.fill = GridBagConstraints.HORIZONTAL;
        gbc_txtPrivateKey.gridx = 1;
        gbc_txtPrivateKey.gridy = 1;
        panel_3.add(txtPrivateKey, gbc_txtPrivateKey);
        txtPrivateKey.setColumns(10);

        btndesEncrypt = new JButton("3DES Encrypt");
        GridBagConstraints gbc_btndesEncrypt = new GridBagConstraints();
        gbc_btndesEncrypt.anchor = GridBagConstraints.WEST;
        gbc_btndesEncrypt.insets = new Insets(0, 0, 5, 5);
        gbc_btndesEncrypt.gridx = 1;
        gbc_btndesEncrypt.gridy = 2;
        panel_3.add(btndesEncrypt, gbc_btndesEncrypt);

        btnAes = new JButton("3DES Decrypt");
        GridBagConstraints gbc_btnAes = new GridBagConstraints();
        gbc_btnAes.insets = new Insets(0, 0, 5, 5);
        gbc_btnAes.anchor = GridBagConstraints.WEST;
        gbc_btnAes.gridx = 2;
        gbc_btnAes.gridy = 2;
        panel_3.add(btnAes, gbc_btnAes);

        btnAesEnrypt = new JButton("AES Enrypt");
        GridBagConstraints gbc_btnAesEnrypt = new GridBagConstraints();
        gbc_btnAesEnrypt.anchor = GridBagConstraints.WEST;
        gbc_btnAesEnrypt.insets = new Insets(0, 0, 5, 5);
        gbc_btnAesEnrypt.gridx = 3;
        gbc_btnAesEnrypt.gridy = 2;
        panel_3.add(btnAesEnrypt, gbc_btnAesEnrypt);

        btnAesDecrypt = new JButton("AES Decrypt");
        GridBagConstraints gbc_btnAesDecrypt = new GridBagConstraints();
        gbc_btnAesDecrypt.anchor = GridBagConstraints.WEST;
        gbc_btnAesDecrypt.insets = new Insets(0, 0, 5, 0);
        gbc_btnAesDecrypt.gridx = 4;
        gbc_btnAesDecrypt.gridy = 2;
        panel_3.add(btnAesDecrypt, gbc_btnAesDecrypt);

        panel_4 = new JPanel();
        tabbedPane.addTab("Find/Replace", null, panel_4, null);
        GridBagLayout gbl_panel_4 = new GridBagLayout();
        gbl_panel_4.columnWidths = new int[] { 0, 0, 0, 0, 0 };
        gbl_panel_4.rowHeights = new int[] { 0, 0, 0, 0 };
        gbl_panel_4.columnWeights = new double[] { 0.0, 0.0, 0.0, 1.0, Double.MIN_VALUE };
        gbl_panel_4.rowWeights = new double[] { 0.0, 0.0, 0.0, Double.MIN_VALUE };
        panel_4.setLayout(gbl_panel_4);

        lblFind = new JLabel("Find:");
        GridBagConstraints gbc_lblFind = new GridBagConstraints();
        gbc_lblFind.insets = new Insets(0, 0, 5, 5);
        gbc_lblFind.anchor = GridBagConstraints.EAST;
        gbc_lblFind.gridx = 0;
        gbc_lblFind.gridy = 0;
        panel_4.add(lblFind, gbc_lblFind);

        textField = new JTextField();
        GridBagConstraints gbc_textField = new GridBagConstraints();
        gbc_textField.gridwidth = 3;
        gbc_textField.insets = new Insets(0, 0, 5, 0);
        gbc_textField.fill = GridBagConstraints.HORIZONTAL;
        gbc_textField.gridx = 1;
        gbc_textField.gridy = 0;
        panel_4.add(textField, gbc_textField);
        textField.setColumns(10);

        lblReplace = new JLabel("Replace:");
        GridBagConstraints gbc_lblReplace = new GridBagConstraints();
        gbc_lblReplace.anchor = GridBagConstraints.EAST;
        gbc_lblReplace.insets = new Insets(0, 0, 5, 5);
        gbc_lblReplace.gridx = 0;
        gbc_lblReplace.gridy = 1;
        panel_4.add(lblReplace, gbc_lblReplace);

        textField_1 = new JTextField();
        GridBagConstraints gbc_textField_1 = new GridBagConstraints();
        gbc_textField_1.gridwidth = 3;
        gbc_textField_1.insets = new Insets(0, 0, 5, 0);
        gbc_textField_1.fill = GridBagConstraints.HORIZONTAL;
        gbc_textField_1.gridx = 1;
        gbc_textField_1.gridy = 1;
        panel_4.add(textField_1, gbc_textField_1);
        textField_1.setColumns(10);

        btnFind = new JButton("Find");
        GridBagConstraints gbc_btnFind = new GridBagConstraints();
        gbc_btnFind.insets = new Insets(0, 0, 0, 5);
        gbc_btnFind.gridx = 1;
        gbc_btnFind.gridy = 2;
        panel_4.add(btnFind, gbc_btnFind);

        btnReplace = new JButton("Replace");
        GridBagConstraints gbc_btnReplace = new GridBagConstraints();
        gbc_btnReplace.insets = new Insets(0, 0, 0, 5);
        gbc_btnReplace.gridx = 2;
        gbc_btnReplace.gridy = 2;
        panel_4.add(btnReplace, gbc_btnReplace);

        chckbxUseRegex = new JCheckBox("Use Regex");
        GridBagConstraints gbc_chckbxUseRegex = new GridBagConstraints();
        gbc_chckbxUseRegex.anchor = GridBagConstraints.EAST;
        gbc_chckbxUseRegex.gridx = 3;
        gbc_chckbxUseRegex.gridy = 2;
        panel_4.add(chckbxUseRegex, gbc_chckbxUseRegex);

        txtpnJavayyyymmddHhmmsssssOracleyyyymmdd = new JTextPane();
        txtpnJavayyyymmddHhmmsssssOracleyyyymmdd.setFont(new Font("Consolas", Font.PLAIN, 12));
        txtpnJavayyyymmddHhmmsssssOracleyyyymmdd
                .setText("JAVA:yyyy-MM-dd HH:mm:ss.SSS\r\nORACLE:YYYY-MM-DD HH24:MI:SS\r\nChinese:\\u4e00-\\u9fa5");
        txtpnJavayyyymmddHhmmsssssOracleyyyymmdd.setEditable(false);
        tabbedPane.addTab("Help", null, txtpnJavayyyymmddHhmmsssssOracleyyyymmdd, null);

        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        setBounds((screenSize.width - 600) / 2, (screenSize.height - 400) / 2, 674, 400);
    }

    private void sha1hashButtonActionPerformed(ActionEvent evt) {
        if (this.textPane.getSelectionEnd() == this.textPane.getSelectionStart()) {
            this.textPane.select(0, this.textPane.getText().length());
        }
        this.resultTextPane.setText(Encoding.hashSHA(this.textPane.getSelectedText()));
    }

    private void md5hashButtonActionPerformed(ActionEvent evt) {
        if (this.textPane.getSelectionEnd() == this.textPane.getSelectionStart()) {
            this.textPane.select(0, this.textPane.getText().length());
        }
        this.resultTextPane.setText(Encoding.hashMD5(this.textPane.getSelectedText()));
    }

    private void base64DecodeButtonActionPerformed(ActionEvent evt) {
        try {
            if (this.textPane.getSelectionEnd() == this.textPane.getSelectionStart()) {
                this.textPane.select(0, this.textPane.getText().length());
            }
            this.resultTextPane.setText(new String(Encoding.base64decode(this.textPane.getSelectedText(),
                    chckbxCrlf.isSelected()), "UTF-8"));
        }
        catch (Throwable t) {
            Runtime.getRuntime().gc();
            t.printStackTrace();
            this.resultTextPane.setText("Exception! " + t.toString());
        }
    }

    private void urlDecodeButtonActionPerformed(ActionEvent evt) {
        if (this.textPane.getSelectionEnd() == this.textPane.getSelectionStart()) {
            this.textPane.select(0, this.textPane.getText().length());
        }
        this.resultTextPane.setText(urlDecode(this.textPane.getSelectedText()));
    }

    private void urlEncodeButtonActionPerformed(ActionEvent evt) {
        if (this.textPane.getSelectionEnd() == this.textPane.getSelectionStart()) {
            this.textPane.select(0, this.textPane.getText().length());
        }
        this.resultTextPane.setText(urlEncode(this.textPane.getSelectedText()));
    }

    private void base64EncodeButtonActionPerformed(ActionEvent evt) {
        try {
            if (this.textPane.getSelectionEnd() == this.textPane.getSelectionStart()) {
                this.textPane.select(0, this.textPane.getText().length());
            }
            this.resultTextPane.setText(Encoding.base64encode(this.textPane.getSelectedText().getBytes("UTF-8"),
                    chckbxCrlf.isSelected()));
        }
        catch (Throwable t) {
            Runtime.getRuntime().gc();
            t.printStackTrace();
            this.resultTextPane.setText("Exception! " + t.toString());
        }
    }

    public static String urlDecode(String str)
    {
        try
        {
            return URLDecoder.decode(str, "utf-8");
        }
        catch (Exception e) {
        }
        return "Decoding error";
    }

    public static String urlEncode(String str)
    {
        try
        {
            return URLEncoder.encode(str, "utf-8");
        }
        catch (Exception e) {
        }
        return "Encoding error";
    }

    public static void main(String[] args) {
        TranscoderFrame tf = new TranscoderFrame();
        tf.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent evt) {
                System.exit(0);
            }
        });
        tf.setVisible(true);
    }

    protected class MyUndoableEditListener
            implements UndoableEditListener
    {
        protected MyUndoableEditListener()
        {
        }

        @Override
        public void undoableEditHappened(UndoableEditEvent e)
        {
            TranscoderFrame.this.undo.addEdit(e.getEdit());
            TranscoderFrame.this.undoAction.updateUndoState();
            TranscoderFrame.this.redoAction.updateRedoState();
        }
    }

    class RedoAction extends AbstractAction
    {
        private static final long serialVersionUID = -2044519935735823050L;

        public RedoAction()
        {
            super();
            setEnabled(false);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            try {
                TranscoderFrame.this.undo.redo();
            }
            catch (CannotRedoException ex) {
                System.out.println("Unable to redo: " + ex);
                ex.printStackTrace();
            }
            updateRedoState();
            TranscoderFrame.this.undoAction.updateUndoState();
        }

        protected void updateRedoState() {
            if (TranscoderFrame.this.undo.canRedo()) {
                setEnabled(true);
                putValue("Name", TranscoderFrame.this.undo.getRedoPresentationName());
            }
            else {
                setEnabled(false);
                putValue("Name", "Redo");
            }
        }
    }

    class UndoAction extends AbstractAction
    {
        private static final long serialVersionUID = -137321944593284589L;

        public UndoAction()
        {
            super();
            setEnabled(false);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            try {
                TranscoderFrame.this.undo.undo();
            }
            catch (CannotUndoException ex) {
                System.out.println("Unable to undo: " + ex);
                ex.printStackTrace();
            }
            updateUndoState();
            TranscoderFrame.this.redoAction.updateRedoState();
        }

        protected void updateUndoState() {
            if (TranscoderFrame.this.undo.canUndo()) {
                setEnabled(true);
                putValue("Name", TranscoderFrame.this.undo.getUndoPresentationName());
            }
            else {
                setEnabled(false);
                putValue("Name", "Undo");
            }
        }
    }
}
